<?php

namespace App\Service\Wechat;



use App\Models\DocumentOrder;
use App\Models\Order;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection;
use EasyWeChat\Payment\Application;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Log;
use Psr\Http\Message\ResponseInterface;

class WechatPayService
{
    public Application $app;
    protected $config;

    public function __construct()
    {
        $isQh = mb_strpos(request()->path(), '/qh_mp/');
        $isQhAdmin = mb_strpos(request()->path(), '/qh/');
        if($isQh || $isQhAdmin) $this->config = config('wechat.qh_payment');
        else $this->config = config('wechat.payment');

        $this->app = new Application($this->config);
    }

    /**
     * 为小程序生成签名
     * @param $prepayId
     * @return array|string
     */
    public function sign($prepayId) {
        return $this->app->jssdk->bridgeConfig($prepayId, false);
    }


    /**
     * 下单
     * @param $params
     * @return array|Collection|object|ResponseInterface|string
     * @throws GuzzleException
     * @throws Exception
     */
    public function order($params) {
        try {

            $result = $this->app->order->unify([
                'body' => $params['body'],
                'out_trade_no' => $params['tradeNo'],
                'total_fee' => $params['fee'],
                'trade_type' => 'JSAPI',
                'openid' => $params['openid']
            ]);
            if ($result['return_code'] != 'SUCCESS' || $result['return_msg'] != 'OK') {
                Log::error('[微信下单][失败]');
                Log::error(json_encode($result));
                throw new Exception('下单失败');
            }

            return $result;
        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 申请退款
     * @param Order $order
     * @return true
     * @throws InvalidConfigException
     * @throws Exception
     */
    public function refund(Order $order): bool
    {
        try {
            $result = $this->app->refund->byOutTradeNumber($order->tradeNo, $order->refundTradeNo, $order->price * 100, $order->price * 100, [
                'notify_url' => $this->config['refund_notify_url']
            ]);
            //Log::debug('[微信退款申请结果]', $result);
            if ($result['return_code'] != 'SUCCESS') {
                Log::error('[微信退款申请失败]');
                Log::error($result);
                throw new Exception('退款申请失败: '.$result['status']);
            }
        }catch (Exception $e) {
            return false;
        }
        Log::debug('[微信退款申请成功] 订单ID：'. $order->id);
        return true;
    }

    /**
     * @param $params
     * @return array|Collection|object|ResponseInterface|string
     * @throws GuzzleException
     */
    public function documentOrder($params) {
        try {

            $result = $this->app->order->unify([
                'body' => $params['body'],
                'out_trade_no' => $params['tradeNo'],
                'total_fee' => $params['fee'],
                'trade_type' => 'JSAPI',
                'openid' => $params['openid'],
                'notify_url' => $this->config['document_notify_url'],
            ]);
            if ($result['return_code'] != 'SUCCESS' || $result['return_msg'] != 'OK') {
                Log::error('[微信下单][失败]');
                Log::error(json_encode($result));
                throw new Exception('下单失败');
            }

            return $result;
        } catch (Exception $e) {
            Log::error($e->getMessage());
            throw new Exception($e->getMessage());
        }
    }

    /**
     * @param DocumentOrder $order
     * @return bool
     * @throws InvalidConfigException
     * @throws Exception
     */
    public function refundByDocumentOrder(DocumentOrder $order): bool
    {
        Log::debug('[微信退款申请]');
        $result = $this->app->refund->byOutTradeNumber($order->tradeNo, $order->refundTradeNo, $order->price * 100, $order->price * 100, [
            'notify_url' => $this->config['document_refund_notify_url']
        ]);
        Log::debug('[微信退款申请结果]', $result);
        if ($result['return_code'] != 'SUCCESS') {
            Log::error('[微信退款申请失败]');
            throw new Exception('退款申请失败: '.$result['status']);
        }

        Log::debug('[微信退款申请成功] 订单ID：'. $order->id);
        return true;
    }

}
